package com.chhuang.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chhuang.annotation.CurrentUser;
import com.chhuang.bean.SaUser;
import com.chhuang.bean.query.UserQo;
import com.chhuang.bean.save.UserSo;
import com.chhuang.bean.view.UserVo;
import com.chhuang.component.I18nMessage;
import com.chhuang.core.bean.Page;
import com.chhuang.core.bean.QueryBean;
import com.chhuang.core.bean.SaResult;
import com.chhuang.core.enums.SaCode;
import com.chhuang.core.exception.SaException;
import com.chhuang.core.valid.ValidationGroups;
import com.chhuang.model.ChUser;
import com.chhuang.service.ChUserService;
import com.chhuang.utils.digest.Md5Util;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName ChUserController
 * @Description ch_user表控制层类(ChUserController)
 * @Author Darren Huang
 * @Date 2022-11-19 18:48:23
 * @Version 1.0
 */
@Slf4j
@RestController
@RequestMapping("/user")
@Api(value = "ChUserController控制类", tags = "ChUserController相关的增删改查接口")
public class ChUserController {
    /**
     * 服务对象
     */
    @Resource
    private ChUserService chUserService;

    /**
     * 获取国际化资源组件
     */
    @Resource
    private I18nMessage i18nMessage;

    /**
     * 分页模糊查询所有数据
     *
     * @param queryBean 分页对象 queryBean;//查询条件
     * @return 所有数据
     */
    @PostMapping("/fuzzyq")
    //说明是什么方法(可以理解为方法注释)
    @ApiOperation(value = "ChUser模糊查询", notes = "根据查询条件和分页条件模糊查询数据的接口")
    @ApiImplicitParam(name = "Authorization", value = "登录令牌", required = true, paramType = "header", dataType = "String")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "返回ChUser信息列表")
    })
    public SaResult<Page<UserVo>> fuzzyq(@ApiParam(name = "page", value = "page分页对象", required = true) @RequestBody QueryBean<UserQo> queryBean) {
        UserQo userQo = queryBean.getQuery();//查询条件
        LambdaQueryWrapper<ChUser> wrapper = null;
        if(userQo!=null) {
            wrapper = Wrappers.lambdaQuery();
            if(StrUtil.isNotBlank(userQo.getUsername())) wrapper.like(ChUser::getUsername, userQo.getUsername());
            if(StrUtil.isNotBlank(userQo.getEmail())) wrapper.like(ChUser::getEmail, userQo.getEmail());
            if(StrUtil.isNotBlank(userQo.getPhone())) wrapper.like(ChUser::getPhone, userQo.getPhone());
            if(StrUtil.isNotBlank(userQo.getNickname())) wrapper.like(ChUser::getNickname, userQo.getNickname());
            if(StrUtil.isNotBlank(userQo.getFirstname())) wrapper.like(ChUser::getFirstname, userQo.getFirstname());
            if(StrUtil.isNotBlank(userQo.getLastname())) wrapper.like(ChUser::getLastname, userQo.getLastname());
            if(userQo.getGender()!=null) wrapper.eq(ChUser::getGender, userQo.getGender());
            if(userQo.getCreateTime()!=null) wrapper.eq(ChUser::getCreateTime, userQo.getCreateTime());
            if(userQo.getModifyTime()!=null) wrapper.eq(ChUser::getModifyTime, userQo.getModifyTime());
        }

        Page<ChUser> queryPage = new Page<>(queryBean);

        return SaResult.data(i18nMessage.get(SaCode.SUCCESS.getCode()), doQuery(wrapper, queryPage, userQo));
    }

    /**
     * 分页查询所有数据
     *
     * @param queryBean 分页对象 queryBean;//查询条件
     * @return 所有数据
     */
    @PostMapping("/query")
    //说明是什么方法(可以理解为方法注释)
    @ApiOperation(value = "ChUser查询", notes = "根据查询条件和分页条件查询数据的接口")
    @ApiImplicitParam(name = "Authorization", value = "登录令牌", required = true, paramType = "header", dataType = "String")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "返回ChUser信息列表")
    })
    public SaResult<Page<UserVo>> query(@ApiParam(name = "page", value = "page分页对象", required = true) @RequestBody QueryBean<UserQo> queryBean) {
        UserQo userQo = queryBean.getQuery();//查询条件

        LambdaQueryWrapper<ChUser> wrapper = null;
        if(userQo!=null) {
            ChUser chUser = new ChUser();
            BeanUtil.copyProperties(userQo, chUser);
            wrapper = Wrappers.lambdaQuery(chUser);
        }

        Page<ChUser> queryPage = new Page<>(queryBean);

        return SaResult.data(i18nMessage.get(SaCode.SUCCESS.getCode()), doQuery(wrapper, queryPage, userQo));
    }

    /**
     * 查询
     * @param wrapper
     * @param page
     * @return
     */
    private Page<UserVo> doQuery(LambdaQueryWrapper<ChUser> wrapper, Page<ChUser> page, UserQo userQo){
        Page iPage = null;
        if(wrapper==null || userQo==null){
            iPage = this.chUserService.page(page);
        }else {
            //按时间区间查询
            if (userQo.getCreateTime() == null && userQo.getCreateTimeStart() != null && userQo.getCreateTimeEnd() != null) {
                wrapper.between(ChUser::getCreateTime, userQo.getCreateTimeStart(), userQo.getCreateTimeEnd());
            }
            if (userQo.getModifyTime() == null && userQo.getModifyTimeStart() != null && userQo.getModifyTimeEnd() != null) {
                wrapper.between(ChUser::getModifyTime, userQo.getModifyTimeStart(), userQo.getModifyTimeEnd());
            }

            iPage = this.chUserService.page(page, wrapper);
        }
        List<ChUser> chUsers = iPage.getRecords();

        if(CollectionUtil.isNotEmpty(chUsers)){
            iPage.setRecords(chUsers.stream().map(u->{
                UserVo userVo = new UserVo();
                BeanUtil.copyProperties(u, userVo);
                return userVo;
            }).collect(Collectors.toList()));
        }

        return iPage;
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("/queryOne/{id}")
    @ApiOperation(value = "ChUser查询一条数据", notes = "根据ID查询一条数据的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "登录令牌", required = true, paramType = "header", dataType = "String"),
            @ApiImplicitParam(name = "id", value = "ChUserid编号", required = true, paramType = "path", dataType = "String")
    })
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "返回一条ChUser信息")
    })
    public SaResult<UserVo> queryOne(@PathVariable Serializable id,
                                     @ApiIgnore @CurrentUser SaUser usrvo) {
        log.info("当前登录的用户信息：{}",JSONUtil.toJsonStr(usrvo));//测试获取当前登录用户信息
        ChUser user= this.chUserService.getById(id);
        if(ObjectUtil.isNotNull(user)) {
            UserVo userVo = new UserVo();
            BeanUtil.copyProperties(user, userVo);
            return SaResult.data(i18nMessage.get(SaCode.SUCCESS.getCode()), userVo);
        }else {
            return SaResult.get(SaCode.SEACH_FAIL.getCode(), i18nMessage.get(SaCode.SEACH_FAIL.getCode()));
        }
    }

    /**
     * 新增数据
     *
     * @param userSo 实体对象
     * @return 新增结果
     */
    @PostMapping("/save")
    @ApiOperation(value = "ChUser的新增", notes = "添加一条数据的接口")
    @ApiImplicitParam(name = "Authorization", value = "登录令牌", required = true, paramType = "header", dataType = "String")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "新增结果")
    })
    public SaResult<UserVo> save(@Validated(ValidationGroups.SaveGroup.class) @RequestBody UserSo userSo) {
        if(this.chUserService.exists(Wrappers.<ChUser>lambdaQuery().eq(ChUser::getUsername, userSo.getUsername()))){
            throw new SaException(SaCode.REGEDIT_USERNAME_ALREADY_EXISTS);
        }
        if(this.chUserService.exists(Wrappers.<ChUser>lambdaQuery().eq(ChUser::getPhone, userSo.getPhone()))){
            throw new SaException(SaCode.REGEDIT_PHONE_ALREADY_EXISTS);
        }
        if(this.chUserService.exists(Wrappers.<ChUser>lambdaQuery().eq(ChUser::getEmail, userSo.getEmail()))){
            throw new SaException(SaCode.REGEDIT_EMAIL_ALREADY_EXISTS);
        }

        ChUser user = new ChUser();
        BeanUtil.copyProperties(userSo, user);
        user.setPassword(Md5Util.md5(user.getPassword(), user.getUsername()));
        Date now = new Date();
        user.setCreateTime(now);
        user.setModifyTime(now);

        if (this.chUserService.save(user)) {
            UserVo userVo = new UserVo();
            BeanUtil.copyProperties(user, userVo);
            return SaResult.data(i18nMessage.get(SaCode.SUCCESS.getCode()), userVo);
        }else {
            return SaResult.get(SaCode.SAVE_FAIL.getCode(), i18nMessage.get(SaCode.SAVE_FAIL.getCode()));
        }
    }

    /**
     * 修改数据
     *
     * @param userSo 实体对象
     * @return 修改结果
     */
    @PutMapping("/modify")
    @ApiOperation(value = "ChUser的修改", notes = "根据ID修改数据的接口")
    @ApiImplicitParam(name = "Authorization", value = "登录令牌", required = true, paramType = "header", dataType = "String")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "修改结果")
    })
    public SaResult<Void> modify(@Validated(ValidationGroups.ModifyGroup.class) @RequestBody UserSo userSo) {
        if(this.chUserService.exists(Wrappers.<ChUser>lambdaQuery()
                .ne(ChUser::getUserId, userSo.getUserId())
                .eq(ChUser::getUsername, userSo.getUsername()))){
            throw new SaException(SaCode.REGEDIT_USERNAME_ALREADY_EXISTS);
        }
        if(this.chUserService.exists(Wrappers.<ChUser>lambdaQuery()
                .ne(ChUser::getUserId, userSo.getUserId())
                .eq(ChUser::getPhone, userSo.getPhone()))){
            throw new SaException(SaCode.REGEDIT_PHONE_ALREADY_EXISTS);
        }
        if(this.chUserService.exists(Wrappers.<ChUser>lambdaQuery()
                .ne(ChUser::getUserId, userSo.getUserId())
                .eq(ChUser::getEmail, userSo.getEmail()))){
            throw new SaException(SaCode.REGEDIT_EMAIL_ALREADY_EXISTS);
        }

        ChUser user = new ChUser();
        BeanUtil.copyProperties(userSo, user);
        user.setPassword(null);
        user.setModifyTime(new Date());

        if (this.chUserService.updateById(user)) {
            return SaResult.ok(i18nMessage.get(SaCode.SUCCESS.getCode()));
        }else {
            return SaResult.get(SaCode.MODIFY_FAIL.getCode(), i18nMessage.get(SaCode.MODIFY_FAIL.getCode()));
        }
    }

    /**
     * 删除数据
     *
     * @param ids 主键拼接字符串
     * @return 删除结果
     */
    @DeleteMapping("/remove")
    @ApiOperation(value = "ChUser的删除", notes = "根据ID集合删除数据的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "登录令牌", required = true, paramType = "header", dataType = "String"),
            @ApiImplicitParam(name = "ids", value = "以逗号“,”隔开的id字符串", required = true, paramType = "query")
    })
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "删除结果")
    })
    public SaResult<Void> remove(@RequestParam("ids") String ids) {
        if (StrUtil.isNotBlank(ids) && this.chUserService.removeBatchByIds(Arrays.asList(ids.split(",")))) {
            return SaResult.ok(i18nMessage.get(SaCode.SUCCESS.getCode()));
        } else {
            return SaResult.get(SaCode.REMOVE_FAIL.getCode(), i18nMessage.get(SaCode.REMOVE_FAIL.getCode()));
        }
    }
}

